/*
 *  class
 *
 *  Real object-orientation for JavaScript
 *
 *  objx.Class([base-class ,][mixin, ] class-definition);
 *
 *  
 *  base-class				The base class
 *  mixin					An object to be mixed in
 *	class-definition		An object defining the class
 *
 */
objx.Class = function() {

	var
		property,
	
		// create the constructor
		klass = function(){
		
			// call the "init" method
			this.init.apply(this, arguments);
			
		},
		
		// save the definition
		definition = arguments[arguments.length - 1]

	;
	
	// set a default init method
	klass.prototype.init = function(){};
	
	// loop through each inherits argument
	for (var i = 0, l = arguments.length - 1; i < l; i++) {

		// get this item
		var item = arguments[i];
		
		// is this a base class?
		if (typeof item == "function") {
			
			// this is a base class
		
			if (objx.debug) {
				if (klass.baseclass) {
					objx.error("Class", "Classes can have only 1 base class.");
				}
			}
		
			// set the baseclass
			klass.baseclass = item;
			
			// extend the prototype
			objx.extend(klass.prototype, item.prototype);
			
		} else {

			// extend the prototype with properties from this item
			objx.extend(klass.prototype, item);
			
		}
		
	}
	
	// create "base_" accessors where needed
	if (klass.baseclass) {
	
		// add the "base_" methods to the klass
		for (property in klass.baseclass.prototype) {
		
			// has this method been overridden?
			if (definition[property]) {
			
				// create accessor
				klass.prototype[objx.Class.basePrefix + property] = klass.baseclass.prototype[property];
			
			}
			
		}
	
	}
	
	// extend the class with the definition
	objx.extend(klass.prototype, definition);
	
	// look for special values
	if (objx.provided("objx.event")) {
		
		for (property in klass.prototype) {
		
			if (klass.prototype[property] == objx.event) {
				
				// add the events

				klass.prototype[property] = (function(property) {
					
					var __property = property;
					
					return function() {
						
						// has this event method been 'exploded' yet?
						if (!this["_ev_" + property]) {
							
							// set the event
							objx(this).event(property);
							
							// set the marker
							this["_ev_" + property] = true;
							
						}
						
						// pass on the call
						this[property].apply(this, arguments);
						
					};
				})(property);
				
			}
		}
		
	}
	
    // set the constructor and classType
    klass.prototype.constructor = klass.prototype.classType = klass;
    
    // return the class
	return klass;

};

objx.Class.basePrefix = "base_";

objx.provides("objx.Class");